﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include "GcmpModelInterface.h"

namespace gcmp
{
    class IDocument;
    class IElement;
    class IFamilyType;

    /*!
    *@brief      冲突解决方式;
    *@author     zhangkai;
    *@date       2021年08月25日
    */
    enum class GCMP_MODEL_INTERFACE_EXPORT ElementsImportStrategy : int32_t
    {
        UseImport = 1,              // 如果有冲突选择使用导入的element;
        UseProject = 2,             // 如果有冲突选择使用项目中的element;
        Rename = 3,                 // 如果有冲突重命名导入的element;
        UnitFamily = 4              // 合并族;
    };

    enum class GCMP_MODEL_INTERFACE_EXPORT ImportFamilyTypeReplaceOption : int32_t
    {
        Replace = 1,            // 替换;
        Delete = 2              // 删除;
    };

    /*!
    *@brief      冲突的element和解决方式信息;
    *@author     zhangkai;
    *@date       2021年08月25日
    */
    struct GCMP_MODEL_INTERFACE_EXPORT ImportElementConflict
    {
        ImportElementConflict() :strategy(ElementsImportStrategy::UseImport) {}
        
        ElementId importElementId;
        std::vector<ElementId> conflictElementId;
        ElementsImportStrategy strategy;
        std::wstring newName;                   // 如果strategy是重命名，那么这是新的名字;

        gcmp::OwnerPtr<gcmp::ImportElementConflict> Clone() const;
    };

    class GCMP_MODEL_INTERFACE_EXPORT IElementImportOption
    {
    public:

        /*!
        *@brief      处理冲突的回调函数;
        *@author     zhangkai;
        *@date       2021年08月25日
        *@param[in]  gcmp::IDocument* pDocument 当前文档
        *@param[in]  gcmp::IElement* pElementImport 当前需要处理的导入的element
        *@param[in]  std::set<gcmp::ElementId>& importElementsId 所有导入的element的ID
        *@param[out] bool& bProcessed 表示是否处理，处理设置为true，不处理设置为false;
        *@return     bool 如果处理，成功返回true，失败返回false;
        */
        virtual bool OnProcessConfilct(gcmp::IDocument* pDocument, gcmp::IElement* pElementImport, std::set<gcmp::ElementId>& importElementsId, bool& bProcessed) = 0;

        /*!
        *@brief      在此显示有冲突的elements，并返回冲突处理方式;
        *@author     zhangkai;
        *@date       2021年08月25日
        *@param[in]  gcmp::IDocument* pDocument 当前文档
        *@param[in]  const std::vector<gcmp::ElementId>& importElementId 导入的element的ID
        *@param[int] const std::unordered_map<ElementId, ElementId, ElementIdHash>& mapOldNewElementId 导入后element ID在新文档和旧文档的映射关系
        *@param[out] std::vector<gcmp::OwnerPtr<gcmp::ImportElementConflict>>& importElementConflict 返回有冲突的element及其解决方式
        *@return     bool 如果处理，成功返回true，失败返回false;
        */
        virtual bool ShowAndGetConflictStrategy(const gcmp::IDocument* pDocument, const std::vector<gcmp::ElementId>& importElementId,
            const std::unordered_map<ElementId, ElementId, ElementIdHash>& mapOldNewElementId, 
            std::vector<gcmp::OwnerPtr<gcmp::ImportElementConflict>>& importElementConflict) = 0;

        /*!
        *@brief      当找不到同名的familyType时，调用此函数决定使用那个familyType或者删除familyType;
        *@author     zhangkai;
        *@date       2021年08月25日
        *@param[in]  const std::wstring& familyName, 族名称
        *@param[in]  const std::wstring& familyTypeName，找不到同名的familyType的名字
        *@param[in]  int instanceCount，实例的个数
        *@param[int] const std::vector<const gcmp::IFamilyType*>& familyTypes，备选的familyType
        *@param[out] std::wstring& replaceFamilyTypeName，用于替换的familyType的名字
        *@return     ImportFamilyTypeReplaceOption Replace表示替换，此时replaceFamilyTypeName不应该为空，Delete表示删除
        */
        virtual ImportFamilyTypeReplaceOption AskFamilyTypeReplaceOption(const std::wstring& familyName, const std::wstring& familyTypeName, int instanceCount,
            const std::vector<const gcmp::IFamilyType*>& familyTypes, std::wstring& replaceFamilyTypeName) = 0;

        /*!
        *@brief      返回是否使用源文档的样式;
        *@author     zhangkai;
        *@date       2023年03月06日
        *@return     bool bUseSourceCategory. true表示使用源文档的样式，false表示使用目标文档的样式;
        */
        virtual bool IsUseSourceCategory() = 0;
    };
}
